<template>
	<!-- 应用效果请查看任务悬赏(H5)的VIP页面中的支付功能
		<payBottom service="XXX" action="XXX" :payInfo="payInfo" :paypopb="paypopb" @payError="payError" @paySuccess="paySuccess" @paypopb="paypopb=false"></payBottom>
		payInfo:接口返回的订单数据（必传）
		paypopb:父组件传给该组件的弹窗显隐状态数据（必传）
		service/action接口核心参数（必传）
		payError:该组件传给父组件的提示信息，用于弹窗提醒（可选，一般是要的）
		paySuccess:支付完成回调（成功）
		apply:支付用途标记，相当于自定义的标记（可选）
		loginCheck:是否开启登录验证，开启之后必须登录才能支付（可选）
		extraData:支付时接口要传的额外数据（可选，一般用不到）
		@paypopb:该组件修改父组件中paypopb的值(一般按照上面写的来即可)
		@giveUp:放弃支付（可选）
	 -->
	<view class="payComponents" v-if="popb&&(!globalData.iOSMiniPay_forbid||service=='shop')">
		<!-- 弹窗 -->
		<view class="payContent" :style="`transform: translateY(${popConb?0:'100%'});`">
			<!-- 关闭按钮 -->
			<image :src="`${imgstatic}close.png?v=${imgVersion}`" mode="aspectFill" class="pc-close"
				@click="closeb=true"></image>
			<!-- 弹窗内容 -->
			<view style="position: relative;">
				<view class="payItemTitle">{{payInfo.subject}}需支付</view>
				<!-- 支付金额和限时时间 -->
				<view class="moneyTitle">
					<view class="title">
						<text>{{ globalData.appConfig.currency ?  globalData.appConfig.currency.symbol : '￥'}}</text>{{payInfo.order_amount}}
					</view>
					<view class="time" v-if="payInfo.timeout>0">支付剩余时间：{{timeout}}</view>
				</view>
				<!-- 支付方式 -->
				<!-- #ifdef H5  -->
				<view class="payMethod" @touchmove.stop @touch.stop>
				<!-- #endif  -->
				<!-- #ifndef H5  -->
				<view class="payMethod">
				<!-- #endif  -->
					<block v-for="(item,index) in payMethods" :key="index">
						<view class="item" v-if="item.pay_code!= 'alipay' || !(platForm == 'web' && globalData.webWeixin)"
							@click.stop="selectMethod(item,index)">
							<view class="methodName" >
								<image :src="item.pay_icon" mode="aspectFill"></image>
								<view>
									<text>{{item.pay_name}}</text>
									<!-- 余额 -->
									<text v-if="item.pay_code=='balance'"
										:style="`opacity:${userInfo.money>=payInfo.order_amount?1:.6}`">
										{{userInfo.money>=payInfo.order_amount?`（可用：${ globalData.appConfig.currency ?  globalData.appConfig.currency.symbol : '￥'}${userInfo.money||0}）`:`（余额不足，可用余额${globalData.appConfig.currency ?  globalData.appConfig.currency.symbol : '￥'}${userInfo.money||0}）`}}
									</text>
									<!-- 购物卡 -->
									<text v-if="item.pay_code=='huoniao_bonus'"
										:style="`opacity:${userInfo.bonus>=payInfo.order_amount?1:.6}`">
										{{userInfo.bonus>=payInfo.order_amount?`（可用：${ globalData.appConfig.currency ?  globalData.appConfig.currency.symbol : '￥'}${userInfo.bonus||0}）`:`（余额不足，可用余额${globalData.appConfig.currency ?  globalData.appConfig.currency.symbol : '￥'}${userInfo.bonus||0}）`}}
									</text>
								</view>
							</view>
							<view class="recharge" v-if="(item.pay_code=='balance'&&userInfo.money<payInfo.order_amount)||
								(item.pay_code=='huoniao_bonus'&&userInfo.bonus<payInfo.order_amount)"
								@click="linkTo(`${globalData.appConfig.cfg_user_index}/${item.pay_code=='balance'?'deposit':'recharge'}.html?paytype=deposit`)">
								充值
							</view>
							<view :class="`selectDot${activeIndex==index?' active':''}`" v-else></view>
						</view>
					</block>
				</view>
				<!-- 支付按钮 -->
				<view class="payNow">
					<view @click="payFn(activeIndex)">立即付款</view>
				</view>
			</view>
		</view>
		<!-- 关闭弹窗提醒 -->
		<view class="closeWarn" v-show="closeb">
			<view class="cw-content">
				<view class="cwc-title">确定放弃本次付款？</view>
				<view class="cwc-time" v-if="payInfo.timeout>0">
					您的订单在{{timeout}}内未支付将被取消，请尽快完成支付
				</view>
				<view class="cwc-btn">
					<view class="cancel" @click="closeFn(true)">放弃</view>
					<view class="continue" @click="closeb=false">继续支付</view>
				</view>
			</view>
		</view>
		<!-- 密码弹窗 -->
		<view class="passwordPop" v-if="passwordb">
			<view class="codeAndkey">
				<!-- 密码输入框 -->
				<view class="passwordInput"
					:style="`transform: translateY(${passwordConb?0:'100%'});${userInfo.paypwdCheck==1?'min-height: 920rpx;':'min-height:1040rpx;'}`">
					<image :src="`${imgstatic}arr_back.png?v=${imgVersion}`" mode="aspectFill" class="cancelPay"
						@click="closeCodeFn"></image>
					<view class="title">输入支付密码</view>
					<view class="payInput">
						<view class="text">请{{userInfo.paypwdCheck==1?'输入':'设置'}}6位数字密码确认支付</view>
						<view class="password">
							<view v-for="index in 6" :key="index" :class="index<=password.length?'active':''">
								<text>•</text>
							</view>
						</view>
						<view class="setCode" v-if="userInfo.paypwdCheck!=1">
							<view>·避免使用连续或重复数字，类似“123456”“112233”</view>
							<view>·避免使用手机号、证件号中的连续数字</view>
						</view>
						<view class="forgetCode"
							@click="linkTo(`${globalData.appConfig.cfg_user_index}/security-paypwdEdit.html?step=2&title=修改支付密码`)"
							v-if="userInfo.paypwdCheck==1">忘记密码?</view>
					</view>
					<div class="confirmPay" v-if="userInfo.paypwdCheck!=1" @click="setAndPayFn">确定并支付</div>
				</view>
				<!-- 键盘 -->
				<view class="keyboard" :style="`transform: translateY(${passwordConb?0:'100%'});`">
					<view>
						<text @click="inputCodeFn(1)">1</text>
						<text @click="inputCodeFn(2)">2</text>
						<text @click="inputCodeFn(3)">3</text>
						<text @click="inputCodeFn(4)">4</text>
						<text @click="inputCodeFn(5)">5</text>
						<text @click="inputCodeFn(6)">6</text>
						<text @click="inputCodeFn(7)">7</text>
						<text @click="inputCodeFn(8)">8</text>
						<text @click="inputCodeFn(9)">9</text>
						<text class="none"></text>
						<text @click="inputCodeFn(0)">0</text>
						<text class="backSpace" :style="`background: url(${imgstatic}del_num.png) no-repeat 50%/60rpx;`"
							@click="password=password.slice(0,-1)"></text>
					</view>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
	var timeoutTimer;

	var certificateTimer;
	const app = getApp();
	export default {
		name: "pay",
		props: {
			payInfo: { //支付返回的信息
				type: Object,
				default: {}
			},
			paypopb: { //弹窗的显隐
				type: Boolean,
				default: false
			},
			service: { //接口核心参数1
				type: String,
				default: ''
			},
			action: { //接口核心参数2
				type: String,
				default: ''
			},
			apply: {
				type: String,
				default: ''
			},
			loginCheck: {
				type: Boolean,
				default: true
			},
			extraData: {
				type: Object,
				default: {}
			}
		},
		data() {
			return {
				// 全局数据
				globalData: app.globalData,
				imgstatic: `${app.globalData.masterDomain}/static/images/miniprograme/payPop/`,
				imgVersion: app.globalData.imgVersion,
				// 接口数据
				payMethods: [{
					id: 0,
					pay_code: 'balance',
					pay_icon: `${app.globalData.masterDomain}/static/images/miniprograme/payPop/balance.png`,
					pay_name: '余额'
				}, ],
				userInfo: {},
				// 辅助数据
				activeIndex: 0,
				formdata: '',
				timeout: '00:00:00',
				password: '',
				// 布尔变量
				popb: false,
				popConb: false,
				closeb: false,
				passwordb: false,
				passwordConb: false,
				ajaxb: false, //支付循环验证
				firstb: true, //首次加载
				paySuccessb: false, //是否执行过支付成功的回调
				// 兼容项
				platForm: app.globalData.platForm, //平台名
			};
		},
		methods: {
			linkTo(url) { //跳转
				if (url) {
					if (app.globalData.platForm == 'web') { //H5
						if (url.indexOf('http') > -1 || window.appBoolean) {
							location.href = url;
						} else {
							uni.navigateTo({
								url: url
							});
						}
					} else { //小程序
						uni.navigateTo({
							url: url.indexOf('http') > -1 ? '/pages/redirect/index?url=' + encodeURIComponent(
								url) : url
						})
					}
				}
			},
			async payMethodData() {
				const _this = this;
				let data = {
					action: 'payment',
					service: 'siteConfig'
				};
				let result = await _this.$ajax.post({
					url: app.encodeUrl(`include/ajax.php?`),
					data: data
				});
				if (result.data.state == 100) {
					if (_this.userInfo.userid) { //如果登录了，那就链接余额数组
						_this.payMethods = _this.payMethods.concat(result.data.info);
						if (_this.userInfo.money < _this.payInfo.order_amount) {
							_this.activeIndex = 1;
						}
					} else { //未登录的话，就覆盖余额数组（相当于没余额选项）
						_this.payMethods = result.data.info;
					}
					console.log(_this.payMethods)
				} else {
					_this.$emit("payError", result.data.info); //给父组件传递错误信息，并弹出提示
				}
			},
			selectMethod(item, index) { //支付方式选择
				const _this = this;
				if (item.pay_code == "balance") {
					if (_this.userInfo.money < _this.payInfo.order_amount) {
						return false
					}
				} else if (item.pay_code == "huoniao_bonus") {
					if (_this.userInfo.bonus < _this.payInfo.order_amount) {
						return false
					}
				}
				_this.formdata = item;
				_this.activeIndex = index;
			},
			closeFn(state) { //关闭弹窗
				const _this = this;
				_this.closeb = false;
				_this.popConb = false;
				setTimeout(res => {
					_this.popb = false;
				}, 300);
				_this.$emit('paypopb', false); //更新父组件弹窗的弹出状态
				_this.$emit('giveUp', state); //放弃支付
				clearTimeout(timeoutTimer); //清除定时器
				clearInterval(certificateTimer);
				if (!_this.ajaxb && !_this.paySuccessb) {
					_this.certificatePayFn();
				}
				_this.$emit('failpayFn'); //支付失败回调
			},
			countdown(time) { //倒计时
				const _this = this;
				let timeout;
				if ((`${time}`).length == 10) { //秒转毫秒
					timeout = time * 1000;
				};
				timeout = (timeout - +new Date()) / 1000; //剩下的秒数
				let seconds = Math.floor(timeout % 60);
				let minutes = Math.floor((timeout % 3600) / 60);
				let hour = Math.floor(timeout / 3600);
				if (seconds > 0 || minutes > 0 || hour > 0) { //还有剩余时间，继续执行
					if ((hour / 10) < 1) {
						hour = '0' + hour;
					};
					if ((minutes / 10) < 1) {
						minutes = '0' + minutes;
					};
					if ((seconds / 10) < 1) {
						seconds = '0' + seconds;
					};
					timeoutTimer = setTimeout(res => {
						_this.timeout = _this.countdown(time);
					}, 1000);
				};
				return hour + ':' + minutes + ":" + seconds
			},
			payFn(index) { //支付弹窗
				const _this = this;
				let item = _this.payMethods[index];
				if (item.pay_code == 'balance') { //余额支付，弹出密码框
					_this.passwordb = true;
					setTimeout(res => {
						_this.passwordConb = true;
					}, 0);
				} else {
					_this.checkPasswordFn();
				}
			},
			closeCodeFn() { //关闭密码输入弹窗
				const _this = this;
				_this.passwordConb = false;
				setTimeout(res => {
					_this.passwordb = false;
				}, 300);
			},
			inputCodeFn(code) { //输入支付密码
				const _this = this;
				_this.password += code;
				if (_this.password.length == 6 && _this.userInfo.paypwdCheck == 1) { //已经设置过密码
					_this.checkPasswordFn();
				};
			},
			async setAndPayFn() { //设置支付密码并支付
				const _this = this;
				let data = {
					service: 'member',
					action: 'updateAccount',
					do: 'paypwdAdd',
					pay1: _this.password,
					pay2: _this.password,
				};
				let result = await _this.$ajax.post({
					url: app.encodeUrl('include/ajax.php?'),
					data: data
				});
				if (result.data.state == 100) {
					await app.memberInfo(_this.userInfo.userid); //用户信息数据更新
					_this.checkPasswordFn(); //验证密码
				}
				_this.$emit("payError", res.data.info); //给父组件传递信息，并弹出提示
			},
			certificatePayFn() { //验证是否支付成功
				const _this = this;
				let type = _this.payInfo.ordernum.split(',').length > 1 ? 1 : '';
				_this.$ajax.post({
					url: app.encodeUrl(
						`include/ajax.php?service=member&action=tradePayResult&order=${_this.payInfo.ordernum}&type=${type}`
					)
				}).then(res => {
					if (res.data.state == 100) {
						_this.paySuccessb = true;
						if (res.data.phone) {
							_this.$emit('paySuccess', res.data);
						} else {
							_this.$emit('paySuccess', res.data.info);
						}
						_this.closeFn(false);
						setTimeout(res => { //paySuccessb使用完之后重置，这里必须异步
							_this.paySuccessb = false;
						})
						app.memberInfo(_this.userInfo.userid, function(info) { //用户信息更新
							_this.userInfo = info;
						});
					}
					_this.ajaxb = false;
				})
			},
			checkPasswordFn() { //提交支付
				const _this = this;
				let index = _this.activeIndex;
				let item = _this.payMethods[index];
				let apple = false;
				let data = {
					service: _this.service,
					action: _this.action,
					ordernum: _this.payInfo.ordernum, //订单号
					paytype: item.pay_code, //支付方式
					..._this.extraData
				};
				if (data.paytype == 'alipay' || data.paytype == 'wxpay') {
					let str = '';
					for (let key in data) {
						str += `&${key}=${data[key]}`;
					};
					str = str.slice(1);
					// 平台切换
					if (_this.platForm == 'web') { //H5，APP
						if (window.appBoolean) { //能到这一步一定是苹果端，安卓端会在父组件被拦截住
							apple = true; //标记
							data['app'] = 1;
							_this.payRequest(data, apple);
						} else { //H5
							location.href = `${_this.globalData.masterDomain}/include/ajax.php?${str}`;
						}
					} else if (_this.platForm == 'mp-toutiao') { //抖音小程序
						let target = encodeURIComponent(`${_this.globalData.masterDomain}/include/ajax.php?${str}`);
						uni.navigateTo({
							url: `/pages/redirect/index?url=${target}&title=${item.pay_name}`
						});
					} else { // 微信小程序
						uni.showToast({
							title: '支付中',
							icon: 'loading',
							mask: true
						});
						_this.payRequest(data, apple, function(res) {
							//调起微信支付
							uni.requestPayment({
								//相关支付参数
								timeStamp: res.data.info.timeStamp,
								nonceStr: res.data.info.nonceStr,
								package: res.data.info.package,
								signType: res.data.info.signType,
								paySign: decodeURIComponent(res.data.info.paySign),
								success: res => {
									_this.certificatePayFn();
								},
								fail: res => {
									_this.$emit("payError", '支付失败'); //给父组件传递信息，并弹出提示
								}
							});
						});
					}
				} else if (item.pay_code == 'balance') {
					data['useBalance'] = 1; //是否使用余额支付:1表示使用
					data['balance'] = _this.payInfo.order_amount; //余额支付的订单金额
					data['paypwd'] = _this.password; //支付密码
					uni.showToast({
						title: '支付中',
						icon: 'loading',
						mask: true
					});
					_this.payRequest(data, apple);;
				} else {
					data['useBalance'] = 0;
					uni.showToast({
						title: '支付中',
						icon: 'loading',
						mask: true
					});
					_this.payRequest(data, apple);;
				}
			},
			payRequest(data, apple, fn = function() {}) { //支付请求
				const _this = this;
				let index = _this.activeIndex;
				let item = _this.payMethods[index];
				_this.$ajax.post({
					url: app.encodeUrl(`include/ajax.php?`),
					data: data
				}).then(res => {
					uni.hideToast();
					if (res.data.state == 100) {
						_this.closeCodeFn();
						if (apple) { //苹果端
							window.setupWebViewJavascriptBridge(function(bridge) {
								bridge.callHandler(item.pay_code == 'wxpay' ? 'wechatPay' :
									'aliPay', {
										"orderInfo": res.data.info
									},
									function(responseData) {});
							});
							return false
						} else if (_this.apply != 'sponsor'&&item.pay_code!='wxpay') { //赞赏不弹出，且非微信支付
							_this.$emit("payError", '支付成功'); //给父组件传递信息，并弹出提示
						}
						_this.closeFn(false);
						fn(res)
					} else {
						_this.$emit("payError", res.data.info || res.data); //给父组件传递信息，并弹出提示
					}
					_this.password = '';
				});
			},
		},
		watch: {
			paypopb(newVal, oldVal) { //弹窗的显隐
				const _this = this;
				let blank = ['{}', '""', 'null', 'undefined'];
				if (blank.includes(JSON.stringify(_this.payInfo))) { //订单信息丢失
					uni.showToast({
						title: '订单信息丢失',
						icon: 'error',
						duration: 1500
					})
					return false
				}
				if (newVal) {
					if(_this.globalData.iOSMiniPay_forbid&&_this.service!='shop'){ //ios支付禁用
						uni.showModal({
							title: '温馨提示',
							content: app.globalData.iosMiniPay_msg||'十分抱歉，由于相关规范，iOS小程序不支持该功能。',
							showCancel: false, //隐藏取消按钮
							success:res=>{
								if(res.confirm){
									_this.$emit('paypopb', false);
								}
							}
						});
						return false
					}
					let userid = app.globalData.userid;
					if (_this.loginCheck && !userid) { //启用登录验证且未登录
						app.tologin();
						return false
					}
					if (_this.firstb) { //首次获取信息
						if (userid) { //登录过了，不管开没开登录验证
							uni.showLoading();
							app.memberInfo(userid, function(info) {
								_this.userInfo = info;
								_this.$nextTick(res => {
									showPop();
								})
								uni.hideLoading();
								//支付方式获取
								_this.payMethodData();
							});
						} else {
							_this.payMethodData();
							_this.$nextTick(res => {
								showPop();
							})
						}
					} else { //已经加载过了
						_this.$nextTick(res => {
							showPop();
						})
					}
					_this.firstb = false; //改变首次载入标记
					if (_this.payInfo.timeout > 0) { //需要倒计时
						let time = parseInt(new Date().valueOf() / 1000) + 1800; //改成支付时间是30分钟
						_this.timeout = _this.countdown(time);
					}

					function showPop() {
						_this.popb = true;
						setTimeout(() => {
							_this.popConb = true;
						});
						certificateTimer = setInterval(res => { //验证支付成功
							if (!_this.ajaxb) {
								_this.ajaxb = true;
								_this.certificatePayFn();
							}
						}, 1000)
					}
				}
			}
		}
	}
</script>

<style>
	@import url("./payBottom.css");
</style>